package co.pushmall.modules.shop.rest;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.pushmall.annotation.AnonymousAccess;
import co.pushmall.aop.log.Log;
import co.pushmall.constant.ShopConstants;
import co.pushmall.enums.OrderInfoEnum;
import co.pushmall.exception.BadRequestException;
import co.pushmall.express.ExpressService;
import co.pushmall.express.dao.ExpressInfo;
import co.pushmall.modules.activity.service.PushMallStorePinkService;
import co.pushmall.modules.shop.domain.PushMallStoreOrder;
import co.pushmall.modules.shop.domain.PushMallStoreOrderStatus;
import co.pushmall.modules.shop.service.PushMallExpressService;
import co.pushmall.modules.shop.service.PushMallStoreOrderService;
import co.pushmall.modules.shop.service.PushMallStoreOrderStatusService;
import co.pushmall.modules.shop.service.PushMallWechatUserService;
import co.pushmall.modules.shop.service.dto.OrderCountDto;
import co.pushmall.modules.shop.service.dto.PushMallExpressDTO;
import co.pushmall.modules.shop.service.dto.PushMallStoreOrderDTO;
import co.pushmall.modules.shop.service.dto.PushMallStoreOrderQueryCriteria;
import co.pushmall.modules.shop.service.dto.PushMallWechatUserDTO;
import co.pushmall.modules.shop.service.param.ExpressParam;
import co.pushmall.mp.service.PushMallTemplateService;
import co.pushmall.utils.OrderUtil;
import co.pushmall.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author pushmall
 * @date 2019-10-14
 */
@Api(tags = "商城:订单管理")
@RestController
@RequestMapping("api")
@Slf4j
public class StoreOrderController {

    @Value("${pushmall.apiUrl}")
    private String apiUrl;


    private final PushMallStoreOrderService pushMallStoreOrderService;
    private final PushMallStoreOrderStatusService pushMallStoreOrderStatusService;
    private final PushMallExpressService pushMallExpressService;
    private final PushMallWechatUserService wechatUserService;
    private final RedisTemplate<String, String> redisTemplate;
    private final PushMallTemplateService templateService;
    private final PushMallStorePinkService storePinkService;
    private final ExpressService expressService;

    public StoreOrderController(PushMallStoreOrderService pushMallStoreOrderService, PushMallStoreOrderStatusService pushMallStoreOrderStatusService,
                                PushMallExpressService pushMallExpressService, PushMallWechatUserService wechatUserService,
                                RedisTemplate<String, String> redisTemplate,
                                PushMallTemplateService templateService, PushMallStorePinkService storePinkService,
                                ExpressService expressService) {
        this.pushMallStoreOrderService = pushMallStoreOrderService;
        this.pushMallStoreOrderStatusService = pushMallStoreOrderStatusService;
        this.pushMallExpressService = pushMallExpressService;
        this.wechatUserService = wechatUserService;
        this.redisTemplate = redisTemplate;
        this.templateService = templateService;
        this.storePinkService = storePinkService;
        this.expressService = expressService;
    }

    /**
     * @Valid 根据商品分类统计订单占比
     */
    @GetMapping("/PmStoreOrder/orderCount")
    @ApiOperation(value = "根据商品分类统计订单占比", notes = "根据商品分类统计订单占比", response = ExpressParam.class)
    public ResponseEntity orderCount() {
        OrderCountDto orderCountDto = pushMallStoreOrderService.getOrderCount();
        return new ResponseEntity(orderCountDto, HttpStatus.OK);
    }

    @GetMapping(value = "/data/count")
    @AnonymousAccess
    public ResponseEntity getCount() {
        return new ResponseEntity(pushMallStoreOrderService.getOrderTimeData(), HttpStatus.OK);
    }

    @GetMapping(value = "/data/chart")
    @AnonymousAccess
    public ResponseEntity getChart() {
        return new ResponseEntity(pushMallStoreOrderService.chartCount(), HttpStatus.OK);
    }

    private Map<String, Object> getPushMallStoreList(PushMallStoreOrderQueryCriteria criteria,
                                                     Pageable pageable,
                                                     String orderStatus,
                                                     String orderType) {
        criteria.setShippingType(1);//默认查询所有快递订单
        //订单状态查询
        if (StrUtil.isNotEmpty(orderStatus)) {
            switch (orderStatus) {
                case "0":
                    criteria.setIsDel(0);
                    criteria.setPaid(0);
                    criteria.setStatus(0);
                    criteria.setRefundStatus(0);
                    break;
                case "1":
                    criteria.setIsDel(0);
                    criteria.setPaid(1);
                    criteria.setStatus(0);
                    criteria.setRefundStatus(0);
                    break;
                case "2":
                    criteria.setIsDel(0);
                    criteria.setPaid(1);
                    criteria.setStatus(1);
                    criteria.setRefundStatus(0);
                    break;
                case "3":
                    criteria.setIsDel(0);
                    criteria.setPaid(1);
                    criteria.setStatus(2);
                    criteria.setRefundStatus(0);
                    break;
                case "4":
                    criteria.setIsDel(0);
                    criteria.setPaid(1);
                    criteria.setStatus(3);
                    criteria.setRefundStatus(0);
                    break;
                case "-1":
                    criteria.setIsDel(0);
                    criteria.setPaid(1);
                    criteria.setRefundStatus(1);
                    break;
                case "-2":
                    criteria.setIsDel(0);
                    criteria.setPaid(1);
                    criteria.setRefundStatus(2);
                    break;
                case "-4":
                    criteria.setIsDel(1);
                    break;
            }
        }
        //订单类型查询
        if (StrUtil.isNotEmpty(orderType)) {
            switch (orderType) {
                case "1":
                    criteria.setBargainId(0);
                    criteria.setCombinationId(0);
                    criteria.setSeckillId(0);
                    break;
                case "2":
                    criteria.setNewCombinationId(0);
                    break;
                case "3":
                    criteria.setNewSeckillId(0);
                    break;
                case "4":
                    criteria.setNewBargainId(0);
                    break;
                case "5":
                    criteria.setShippingType(2);
                    break;
            }
        }
        return pushMallStoreOrderService.queryAll(criteria, pageable);
    }


    @ApiOperation(value = "查询订单")
    @GetMapping(value = "/PmStoreOrder")
    @PreAuthorize("@el.check('admin','YXSTOREORDER_ALL','YXSTOREORDER_SELECT')")
    public ResponseEntity getPushMallStoreOrders(PushMallStoreOrderQueryCriteria criteria,
                                                 Pageable pageable,
                                                 @RequestParam(name = "orderStatus") String orderStatus,
                                                 @RequestParam(name = "orderType") String orderType) {
        return new ResponseEntity(getPushMallStoreList(criteria, pageable, orderStatus, orderType), HttpStatus.OK);
    }


    @ApiOperation(value = "发货")
    @PutMapping(value = "/PmStoreOrder")
    @PreAuthorize("@el.check('admin','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity update(@Validated @RequestBody PushMallStoreOrder resources) {
        if (StrUtil.isBlank(resources.getDeliveryName())) {
            throw new BadRequestException("请选择快递公司");
        }
        if (StrUtil.isBlank(resources.getDeliveryId())) {
            throw new BadRequestException("快递单号不能为空");
        }
        PushMallExpressDTO expressDTO = pushMallExpressService.findById(Integer.valueOf(resources
                .getDeliveryName()));
        if (ObjectUtil.isNull(expressDTO)) {
            throw new BadRequestException("请先添加快递公司");
        }
        resources.setStatus(1);
        resources.setDeliveryType("express");
        resources.setDeliveryName(expressDTO.getName());
        resources.setDeliverySn(expressDTO.getCode());

        pushMallStoreOrderService.update(resources);

        PushMallStoreOrderStatus storeOrderStatus = new PushMallStoreOrderStatus();
        storeOrderStatus.setOid(resources.getId());
        storeOrderStatus.setChangeType("delivery_goods");
        storeOrderStatus.setChangeMessage("已发货 快递公司：" + resources.getDeliveryName()
                + " 快递单号：" + resources.getDeliveryId());
        storeOrderStatus.setChangeTime(OrderUtil.getSecondTimestampTwo());

        pushMallStoreOrderStatusService.create(storeOrderStatus);

        //模板消息通知
        try {
            PushMallWechatUserDTO wechatUser = wechatUserService.findById(resources.getUid());
            if (ObjectUtil.isNotNull(wechatUser)) {
                //公众号与小程序打通统一公众号模板通知
                if (StrUtil.isNotBlank(wechatUser.getOpenid())) {
                    templateService.deliverySuccessNotice(resources.getOrderId(),
                            expressDTO.getName(), resources.getDeliveryId(), wechatUser.getOpenid());
                }
            }
        } catch (Exception e) {
            log.info("当前用户不是微信用户不能发送模板消息哦!");
        }

        //加入redis，7天后自动确认收货
        String redisKey = String.valueOf(StrUtil.format("{}{}",
                ShopConstants.REDIS_ORDER_OUTTIME_UNCONFIRM, resources.getId()));
        redisTemplate.opsForValue().set(redisKey, resources.getOrderId(),
                ShopConstants.ORDER_OUTTIME_UNCONFIRM, TimeUnit.DAYS);


        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }

    @ApiOperation(value = "订单核销")
    @PutMapping(value = "/PmStoreOrder/check")
    @PreAuthorize("@el.check('admin','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity check(@Validated @RequestBody PushMallStoreOrder resources) {
        if (StrUtil.isBlank(resources.getVerifyCode())) {
            throw new BadRequestException("核销码不能为空");
        }
        PushMallStoreOrderDTO storeOrderDTO = pushMallStoreOrderService.findById(resources.getId());
        if (!resources.getVerifyCode().equals(storeOrderDTO.getVerifyCode())) {
            throw new BadRequestException("核销码不对");
        }
        if (OrderInfoEnum.PAY_STATUS_0.getValue().equals(storeOrderDTO.getPaid())) {
            throw new BadRequestException("订单未支付");
        }

        /**
         if(storeOrderDTO.getStatus() > 0) throw new BadRequestException("订单已核销");

         if(storeOrderDTO.getCombinationId() > 0 && storeOrderDTO.getPinkId() > 0){
         PushMallStorePinkDTO storePinkDTO = storePinkService.findById(storeOrderDTO.getPinkId());
         if(!OrderInfoEnum.PINK_STATUS_2.getValue().equals(storePinkDTO.getStatus())){
         throw new BadRequestException("拼团订单暂未成功无法核销");
         }
         }
         **/

        //远程调用API
        RestTemplate rest = new RestTemplate();
        String url = StrUtil.format(apiUrl + "/order/admin/order_verific/{}", resources.getVerifyCode());
        String text = rest.getForObject(url, String.class);

        JSONObject jsonObject = JSON.parseObject(text);

        Integer status = jsonObject.getInteger("status");
        String msg = jsonObject.getString("msg");

        if (status != 200) {
            throw new BadRequestException(msg);
        }


        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }


    @ApiOperation(value = "退款")
    @PostMapping(value = "/PmStoreOrder/refund")
    @PreAuthorize("@el.check('admin','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity refund(@Validated @RequestBody PushMallStoreOrder resources) {
        pushMallStoreOrderService.refund(resources);

        //模板消息通知
        try {
            PushMallWechatUserDTO wechatUser = wechatUserService.findById(resources.getUid());
            if (ObjectUtil.isNotNull(wechatUser)) {
                //公众号与小程序打通统一公众号模板通知
                if (StrUtil.isNotBlank(wechatUser.getOpenid())) {
                    templateService.refundSuccessNotice(resources.getOrderId(),
                            resources.getPayPrice().toString(), wechatUser.getOpenid(),
                            OrderUtil.stampToDate(resources.getAddTime().toString()));
                }
            }
        } catch (Exception e) {
            log.info("当前用户不是微信用户不能发送模板消息哦!");
        }


        return new ResponseEntity(HttpStatus.NO_CONTENT);
    }


    @Log("删除")
    @ApiOperation(value = "删除")
    @DeleteMapping(value = "/PmStoreOrder/{id}")
    @PreAuthorize("@el.check('admin','YXSTOREORDER_ALL','YXSTOREORDER_DELETE')")
    public ResponseEntity delete(@PathVariable Integer id) {
        //if(StrUtil.isNotEmpty("22")) throw new BadRequestException("演示环境禁止操作");
        pushMallStoreOrderService.delete(id);
        return new ResponseEntity(HttpStatus.OK);
    }


    @Log("修改订单")
    @ApiOperation(value = "修改订单")
    @PostMapping(value = "/PmStoreOrder/edit")
    @PreAuthorize("hasAnyRole('admin','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity editOrder(@RequestBody PushMallStoreOrder resources) {
        if (ObjectUtil.isNull(resources.getPayPrice())) {
            throw new BadRequestException("请输入支付金额");
        }
        if (resources.getPayPrice().doubleValue() < 0) {
            throw new BadRequestException("金额不能低于0");
        }

        PushMallStoreOrderDTO storeOrder = pushMallStoreOrderService.findById(resources.getId());
        //判断金额是否有变动,生成一个额外订单号去支付

        int res = NumberUtil.compare(storeOrder.getPayPrice().doubleValue(), resources.getPayPrice().doubleValue());
        if (res != 0) {
            String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
            resources.setExtendOrderId(orderSn);
        }


        pushMallStoreOrderService.update(resources);

        PushMallStoreOrderStatus storeOrderStatus = new PushMallStoreOrderStatus();
        storeOrderStatus.setOid(resources.getId());
        storeOrderStatus.setChangeType("order_edit");
        storeOrderStatus.setChangeMessage("修改订单价格为：" + resources.getPayPrice());
        storeOrderStatus.setChangeTime(OrderUtil.getSecondTimestampTwo());

        pushMallStoreOrderStatusService.create(storeOrderStatus);
        return new ResponseEntity(HttpStatus.OK);
    }

    @Log("修改订单备注")
    @ApiOperation(value = "修改订单备注")
    @PostMapping(value = "/PmStoreOrder/remark")
    @PreAuthorize("hasAnyRole('admin','YXSTOREORDER_ALL','YXSTOREORDER_EDIT')")
    public ResponseEntity editOrderRemark(@RequestBody PushMallStoreOrder resources) {
        if (StrUtil.isBlank(resources.getRemark())) {
            throw new BadRequestException("请输入备注");
        }
        pushMallStoreOrderService.update(resources);
        return new ResponseEntity(HttpStatus.OK);
    }


    /**
     * @Valid 获取物流信息, 根据传的订单编号 ShipperCode快递公司编号 和物流单号,
     */
    @PostMapping("/PmStoreOrder/express")
    @ApiOperation(value = "获取物流信息", notes = "获取物流信息", response = ExpressParam.class)
    public ResponseEntity express(@RequestBody ExpressParam expressInfoDo) {
        ExpressInfo expressInfo = expressService.getExpressInfo(expressInfoDo.getOrderCode(),
                expressInfoDo.getShipperCode(), expressInfoDo.getLogisticCode());
        if (!expressInfo.isSuccess()) {
            throw new BadRequestException(expressInfo.getReason());
        }
        return new ResponseEntity(expressInfo, HttpStatus.OK);
    }

    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/PmStoreOrder/download")
    @PreAuthorize("@el.check('admin','yxStoreOrder:list')")
    public void download(HttpServletResponse response,
                         PushMallStoreOrderQueryCriteria criteria,
                         Pageable pageable,
                         @RequestParam(name = "orderStatus") String orderStatus,
                         @RequestParam(name = "orderType") String orderType,
                         @RequestParam(name = "listContent") String listContent) throws IOException, ParseException {

        if (StringUtils.isEmpty(listContent)) {
            List<PushMallStoreOrderDTO> list = (List) getPushMallStoreList(criteria, pageable, orderStatus, orderType).get("content");
            pushMallStoreOrderService.download(list, response);
        } else {
            List<String> idList = JSONArray.parseArray(listContent).toJavaList(String.class);
            List<PushMallStoreOrderDTO> pushMallStoreOrderDTOS = pushMallStoreOrderService.findByIds(idList);

            pushMallStoreOrderService.download(pushMallStoreOrderDTOS, response);
        }
    }

}
